package lyl.link;


public class MyOneWayLinkList {

    private Node head;
    private static volatile int size;
    class Node{
        private int val;

        private Node next;

        public Node() {
        }

        public Node(int val) {
            this.val = val;
        }

        public int getVal() {
            return val;
        }

        public void setVal(int val) {
            this.val = val;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }

    public void add(int val){
        Node newNode = new Node(val);
        if(this.head == null){
            this.head = newNode;
        } else {
            Node node = this.head;
            while(node.next !=null){
                node = node.next;
            }
            node.next = newNode;
        }
        size++;
    }

    public void reverseLinkedList(){

        if(head == null || head.next == null){
            return;
        }
        Node node = doReverse(head);
        head = node;

    }

    public void reverseLinkedList(int m,int n){

        Node node = doReverse(head,m,n);
        head = node;

    }

    //链表翻转
    private Node doReverse(Node head){
        if(head ==null){
            return head;
        }
        Node prev = head;
        Node current = head.next;
        //1->2->3
        //1 2->3
        prev.next = null;

        while(current!=null){
            //3
            Node next =  current.next;
            //1<-2 3
            current.next = prev;
            //2
            prev = current;
            //3
            current = next;
        }

        return prev;

    }
    //链表翻转
    private Node doReverse(Node head,int m,int n) throws RuntimeException {
        if(head == null || m>=n){
            return head;
        }
        if(m<=0 || n >size){
            throw new RuntimeException("越界了");
        }
        Node dummy = new Node(-1);
//-1,1,2,3,4,5,6,7
        dummy.next =head;
        head = dummy;

        for(int i = 1 ;i<m ;i++){
            head = head.next;
        }
        //1
        Node preM = head;
        //2
        Node mNode = head.next;
        //2
        Node nNode = mNode; //prev
        //3
        Node postN = nNode.next; //current

        for(int i=m;i<n;i++){
            //4
            Node next = postN.next;
            //3指向2
            postN.next = nNode;
            //3
            nNode = postN;
            //4
            postN = next;
        }
        preM.next = nNode;//指向prev
        mNode.next = postN;//断开2到3的连接指向5

        return dummy.next;
    }

    public void print(){
        Node node = head;
        if(head == null){
            System.out.println("nil");
            return;
        }
        while(node!=null){
            System.out.print(node.getVal());
            node = node.next;
            if(node!=null){
                System.out.print("->");
            }
        }
        System.out.println("\n");
    }

    public int size(){
       return size;
    }

    //两数相加,反向
    public Node addTwoNumbers(Node l1,Node l2){
        if(l1 == null){
            return l2;
        }
        if(l2 == null){
            return l1;
        }
        Node dummy = new Node(0);//移动指针
        Node pre = dummy;//返回
        int carry = 0; //进位情况
        while(l1!=null && l2!=null){
            int total = l1.val + l2.val + carry;
            int number = total % 10;
            carry = total / 10;
            Node node = new Node(number);
            dummy.next = node;
            dummy = dummy.next;
            l1 = l1.next;
            l2 = l2.next;
        }
        while(l1!=null){
            int total = l1.val + carry;
            int number = total % 10;
            carry = total / 10;
            Node node = new Node(number);
            dummy.next = node;
            dummy = dummy.next;
            l1 = l1.next;
        }
        while(l2!=null){
            int total = l2.val + carry;
            int number = total % 10;
            carry = total / 10;
            Node node = new Node(number);
            dummy.next = node;
            dummy = dummy.next;
            l2 = l2.next;
        }
        if(carry != 0){
            Node node = new Node(carry);
            dummy.next = node;
        }

        return pre.next;

    }

    //两数相加，正向
    public Node addTwoNumbers1(Node l1 , Node l2){
        l1 = doReverse(l1);
        l2 = doReverse(l2);
        return doReverse(addTwoNumbers(l1,l2));
    }

}
